assume ds:data,cs:code,es:table,ss:stack

data segment
        ;以下是表示21年的21个字符串
        db 	'1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db	'1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db 	'1993','1994','1995'
        
;以下是表示21年公司总收的21个dword型数据
        dd 	16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 	345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
        
;以下是表示21年公司雇员人数的21个word型数据
        dw 	3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 	11542,14430,45257,17800        
data ends

table segment
        db 21 dup('year summ ne ?? ')
table ends

data_sorted segment
    db 	10 	dup (0)
data_sorted ends

stack segment
	db	30 	dup (0)
stack ends

code segment
start: 

	mov	ax,data
	mov	ds,ax
	mov	ax,table
	mov	es,ax
	
	mov ax,stack
	mov ss,ax
	mov sp,30

    ; 复制到table数据段
	call copy_info							

    mov bx,0
	mov ax,data_sorted
    mov ds,ax
    mov si,0

    ; 清屏留出位置
	call clear_screen

    mov cx,21        
	mov dh,1
    ;dh表示要显示的行数

show_info: 
    push cx
	; 年份
    mov ax,es:[bx]
    mov ds:[si],ax
    mov ax,es:[bx+2]
    mov ds:[si+2], ax

    mov byte ptr ds:[si+4],0

	;第4列
    mov dl,4   								
    mov ch,0
    ;设置颜色，00000111b表示白底黑字这样才能看到
    mov cl,00000111b
    call show_str

    push dx;显示总收入
    mov ax,es:[bx+5]
    mov dx,es:[bx+7]  
    call dtoc
    pop dx            

    mov dl,14
    mov ch,0         
    mov cl,00000111b
    call show_str

    push dx
    mov ax,es:[bx+10]
    mov dx,0
    call dtoc
    pop dx

    mov dl,34
    mov ch,0
    mov cl,00000111b
    call show_str

    push dx
    mov ax,es:[bx+13]
    mov dx,0
    call dtoc
    pop dx

    mov dl,50
    mov ch,0          
    mov cl,00000111b
    call show_str

    add bx,16      
    add dh,1 
    pop cx 
    loop show_info
 
    mov ax,4c00H
    int 21H
	
clear_screen:
    push es            

    mov ax,0b800H
    mov es,ax
	
	mov di,0

show_nothing:
	mov byte ptr es:[di+160],' '
	mov byte ptr es:[di+161],00000000b
	add di,2
	cmp di,160*21
	jne show_nothing

	pop es
	ret	
	
copy_info:		
    ;初始化偏移地址
	mov	si,0								
	mov	di,0
	;雇员人数的偏移地址
	mov bp,168
	
	mov	cx,21

s:		
    ;年份
	mov	ax,[si]
	mov	es:[di],ax
	mov	ax,[si+2]
	mov	es:[di+2],ax
	
	mov	byte ptr es:[di+4],' '

    ;总收入，方便除法计算
	mov	ax,[si+84]
	mov	es:[di+5],ax
	mov	dx,[si+86]
	mov	es:[di+7],dx
	
	mov	byte ptr es:[di+9],' '
	;人数
	mov	bx,ds:[bp]
	add bp,2
	mov	es:[di+10],bx
	
	mov	byte ptr es:[di+12],' '
	
	mov	bx,es:[di+10]
    ; 除法
	div bx
	mov es:[di+13],ax
	
	mov	byte ptr es:[di+15],' '

	add	si,4
	add	di,16
	loop	s
	
    ret


dtoc:    
    push si
    mov si, 0  

change:
	mov cx,10
    call divdw     
	
    push ax
    push dx

    add ax,dx
    mov cx,ax
    pop dx
    pop ax

    add bp,48
    push bp
    inc si
	jcxz ending						

    jmp short change

ending: 
    mov cx,si
    mov si,0

write:
	pop ds:[si]

    inc si
    loop write
    ;在最后一个ASCII码后面写入0，表示字符串结束
    mov byte ptr ds:[si], 0

    pop si
    ret

divdw: 
	push bx
    push ax
    mov ax,dx
    mov dx,0
    ;dx|ax除以cx，ax存储商（高16位），dx存储余数（对于下一次除法，恰好实现余数放在高16位）
    div cx
    mov bx,ax

    pop ax
    div cx
    mov bp,dx 
    mov dx,bx
	pop bx
    ret

;显示字符串，ds指向的数据段为显示的字符串，cl为颜色，dh为行数，dl为列数
show_str:  
    push si            
    push bx            
    push es            

    mov ax,0b800H
    mov es,ax    

    mov ax,0
    mov al,160
    mul dh
    mov bx,ax
    mov ax,0
    mov al,2          
    mul dl
    add bx,ax

	mov si,0
    mov di,0
    mov al,cl
    mov ch,0
show:
	mov cl,ds:[si]
    ;结束
    jcxz ok
    ;将需要显示的内容写入缓冲区
	mov es:[bx+di+0], cl
    mov es:[bx+di+1], al
    ;di：缓冲区数据偏移量
    add di,2								
    ;si：data_sorted数据段数据偏移量
    inc si
    jmp short show

ok: pop es         
    pop bx
    pop si             
    ret
	
code ends
end start
